<?php


namespace App\Support;

use App\Enums\BaseErrorCode;
use App\Exceptions\Custom\ResponseHttpException;
use Illuminate\Contracts\Encryption\EncryptException;
use Illuminate\Encryption\Encrypter;
use Kuafu\IpWhite\Service\IpWhiteService;


class AppletEncrypt
{
    protected static $key;
    protected static $cipher;
    private static   $instance = null;

    public function __construct()
    {

        self::$key    = config('app.key');
        self::$cipher = config('app.cipher');
    }

    public static function getInstance()
    {
        //判断实例有无创建，没有的话创建实例并返回，有的话直接返回
        if (!(self::$instance instanceof self)) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    private function __clone() { }

    /**
     * 生成token
     * @param $siteConfig
     * @param $userId
     * @param $username
     * @param $mobile
     * @return string
     */
    public static function encryptData($siteConfig, $userId, $username, $mobile, string $feishuId, string $ip): string
    {
        $data  = [
            'time'         => time(),
            'openId'       => $appId = $siteConfig['appId'],
            'platformName' => $siteConfig['platformName'],
            'ext'          => $siteConfig['ext'],
            'inv'          => $siteConfig['inv'],
            'salt'         => self::$cipher,
            'userId'       => $userId,
            'username'     => $username,
            'mobile'       => $mobile,
            'feishuId'     => $feishuId,
            'ip'           => $ip,
        ];

        $value = json_encode($data);
        $res =  self::encrypt($value);

        // 白名单登录
        (new IpWhiteService($userId, $appId, null))->login($ip);

        return $res;
    }

    /**
     * 检测token是否过期,失效刷新
     * @param $token
     * @param string $key
     * @return string
     */
    public static function checkExpireToken($token, $key = '')
    {
        //获取token信息
        $data = self::decryptData($token, $key);
        //如果当前实现大于token失效实现，就刷新token
        if (time() > $data['time'] + $data['ext']) {
            throw new ResponseHttpException(BaseErrorCode::$TOKEN_IS_EXPIRE);
        }
    }

    /**
     * 检查token是否失效,过期重新登录
     * @param $token
     * @param string $key
     */
    public static function checkInvalidToken($token, $key = '')
    {
        //获取token信息
        $data = self::decryptData($token, $key);
        //如果当前实现大于token失效时间，提示用户重新登录
        if (time() > $data['time'] + $data['inv']) {
            throw new ResponseHttpException(BaseErrorCode::$TOKEN_IS_INVALID);
        }
    }

    /**
     * 解密数据转数组
     * @param $value
     * @param string $key
     * @return mixed
     */
    public static function decryptData($value, $key = '')
    {

        $decrypt = self::decrypt($value, $key);
        return json_decode($decrypt, true);
    }

    /**
     * 加密字符串
     * @param $value
     * @return string
     */
    public static function encrypt($value): string
    {
        try {
            $encrypt = new Encrypter(substr(self::$key, -32), self::$cipher);
            return $encrypt->encrypt($value);
        } catch (EncryptException $encryptException) {
            //todo 异常
        }
    }

    /**
     * 解密字符串
     * @param $payload
     * @param string $key
     * @return mixed
     */
    public static function decrypt($payload, $key = '')
    {
        if (!$key) {
            $key = self::$key;
        }
        try {
            $encrypt = new Encrypter(substr($key, -32), self::$cipher);
            return $encrypt->decrypt($payload);
        } catch (EncryptException $encryptException) {
            //todo 异常
        }
    }
}
